package modelApp

import java.util.List
import model.Detective
import model.Lugar
import model.Pais
import model.Partida
import model.Villano
import org.uqbar.commons.model.ObservableUtils
import org.uqbar.commons.utils.Observable

abstract class DesarrolloCasoAppModel {
	
	@Property Detective detective
	
	new (Detective detective){
		this.detective = detective
	}

}

@Observable
class ViajarMisterioAppModel extends DesarrolloCasoAppModel{
	
	@Property Partida partida
	@Property Pais paisAnterior
	Pais paisSeleccionado
	@Property var Boolean puedeVolverAtras = false
	@Property var Boolean puedeViajar = false
	@Property ContenedorInformacionViaje container
	
	
	new(Partida partida, ContenedorInformacionViaje container){
		super(partida.detective)
		this.container = container
		this.partida = partida
		this.paisAnterior = this.detective.paisAnterior
		if (this.paisAnterior != null)
			this.puedeVolverAtras = true
	}
	/**
	 * Setter del pais seleccionado.
	 */
	def void setPaisSeleccionado(Pais pais) {
		this.paisSeleccionado = pais
		this.puedeViajar = true
	}
	
	/**
	 * Getter del pais seleccionado.
	 */
	def Pais getPaisSeleccionado() { this.paisSeleccionado }
	
	/**
	 * Mueve el detective al pais seleccionado, desencadenando una seria de eventos.
	 */
	def viajarAPais() {
		this.container.agregarPaisRecorrido(this.paisSeleccionado)
		this.partida.moverVillanoSiEsNecesario(this.paisSeleccionado)
		if(!this.partida.recorridoDelVillano.paisActual.equals(this.paisSeleccionado))
			this.container.agregarDestinoFallido(this.paisSeleccionado)
		this.detective.viajarAlSiguientePais(this.paisSeleccionado)
		this.puedeViajar = false
		this.puedeVolverAtras = true
	}
	
	/**
	 * Mueve el detective hacia el pais anterior
	 */
	def volverAlPaisAnterior(){
		this.container.agregarPaisRecorrido(this.paisSeleccionado)	
		this.detective.volverAlPaisAnterior	
	}
	
	
	
}

@Observable
class OrdenDeArrestoAppModel extends DesarrolloCasoAppModel {
	
	@Property  val List<Villano> villanos
	 Villano villanoAcusar
	@Property Boolean puedeAgregar = false
	
	new(Detective detective, List<Villano> villanos){
		super(detective)
		this._villanos = villanos
	}
	
	/**
	 * Setter variable villanoAcusar
	 */
	def void setVillanoAcusar(Villano villano){
		this.villanoAcusar = villano
		this.puedeAgregar = true
	}
	
	/**
	 * getter de variable villanoAcusar
	 */
	def Villano getVillanoAcusar() { this.villanoAcusar }
	
	/**
	 * Genera una nueva orden de arresto y se la asigna al detective.
	 */
	def generarOrdenDeArresto() {
		this.detective.generarOrdenDeArrestoPara(this.villanoAcusar)
		this.puedeAgregar = false
		ObservableUtils.firePropertyChanged(this.detective.ordenArresto, "villanoAcusado", villanoAcusar)	
	}
}

@Observable
class VisitarLugarAppModel extends DesarrolloCasoAppModel {
	
	@Property Lugar lugarAVisitar
	@Property Partida partida
	
	new (Partida partida, int numeroDeLugar) {
		super(partida.detective)
		this.lugarAVisitar = this.detective.paisActual.lugaresInteresantes.get(numeroDeLugar)
		this.partida = partida
	}
	
	/**
	 * Visita un lugar, dandole las pistas al detective.
	 */
	def visitar() {
		this.detective.consultar(this.lugarAVisitar)
		this.lugarAVisitar.consultar
	}
	
	/**
	 * Comprueba si el lugar que visita contiene al villano
	 */
	def finDelJuego(){
		this.lugarAVisitar.contieneAlVillano
	}
}